# +----------------------------------------------------------------------
# | ChatWork智能聊天办公系统
# +----------------------------------------------------------------------
# | 软件声明: 本系统并非自由软件,未经授权任何形式的商业使用均属非法。
# | 版权保护: 任何企业和个人不允许对程序代码以任何形式任何目的复制/分发。
# | 授权要求: 如有商业使用需求,请务必先与版权所有者取得联系并获得正式授权。
# +----------------------------------------------------------------------
# | Author: ChatWork Team <2474369941@qq.com>
# +----------------------------------------------------------------------
from typing import Dict
from fastapi import Query
from pydantic import BaseModel, Field


class AiModelsSearchIn(BaseModel):
    """ AI模型搜索参数 """
    scene: str = Query(..., description="模型场景: [对话=chat,向量=vector]")


class AiModelsDetailIn(BaseModel):
    """ AI模型详情参数 """
    id: int = Query(..., gt=0, description="模型ID")


"""--------------- Separator ---------------"""


class AiModelsAddIn(BaseModel):
    scene: str = Field(..., pattern=r"^(chat|vector|ranking)$", description="模型场景")
    channel: str = Field(..., max_length=100, description="模型通道: [openai, zhipu, ...]")
    logo: str = Field(..., max_length=250, description="模型图标")
    mark: str = Field(..., max_length=100, description="模型标识")
    name: str = Field(..., max_length=100, description="模型名称")
    intro: str = Field(default="", max_length=800, description="模型描述")
    config: dict = Field(..., description="配置信息")
    models: list = Field(..., description="模型列表")
    is_disable: int = Field(default=0, ge=0, le=1, description="是否禁用: [0=否, 1=是]")

    @classmethod
    def messages(cls):
        return {
            "scene.missing": "请填选择模型场景",
            "scene.pattern": "模型场景异常: [chat, vector]",
            "logo.missing": "请设置模型图标",
            "logo.max_length": "模型图片路径不能超250个字符",
            "mark.missing": "请填写模型标识",
            "mark.max_length": "模型标识不能超出100个字符",
            "name.missing": "请填写模型名称",
            "name.max_length": "模型名称不能超出100个字符",
            "intro.max_length": "模型描述不能超出800个字符",
            "config.missing": "模型配置参数缺失",
            "models.missing": "至少需要1个子模型",
            "is_disable.ge": "模型状态非合法值: [0, 1]",
            "is_disable.le": "模型状态非合法值: [0, 1]"
        }

    class Config:
        json_schema_extra = {
            "example": {
                "scene": "chat",
                "channel": "openai",
                "logo": "https://www.xx.cn/images/gpt35.png",
                "mark": "openai",
                "name": "OpenAI",
                "intro": "OpenAI",
                "is_disable": 0,
                "config": {
                    "context_num": 4,
                    "temperature": 1.0,
                    "presence_penalty": 0.0,
                    "frequency_penalty": 0.0,
                    "check_key": 1,
                    "agency_api": "",
                    "global_directives": ""
                },
                "models": [
                    {
                        "model": "gpt-3.5-turbo",
                        "alias": "gpt35",
                        "price": 0.001,
                        "status": 1
                    },
                    {
                        "model": "gpt-3.5-turbo-0125",
                        "alias": "gpt35-turbo-0125",
                        "price": 0.002,
                        "status": 1
                    }
                ]
            }
        }


class AiModelsEditIn(BaseModel):
    id: int = Field(..., gt=0, description="ID")
    channel: str = Field(..., max_length=100, description="模型通道: [openai, zhipu, ...]")
    logo: str = Field(..., max_length=250, description="模型图标")
    name: str = Field(..., max_length=100, description="模型名称")
    intro: str = Field(max_length=800, default="", description="模型描述")
    config: dict = Field(description="配置信息")
    models: list = Field(description="模型列表")
    is_disable: int = Field(ge=0, le=1, default=0, description="是否禁用: [0=否, 1=是]")

    @classmethod
    def messages(cls):
        return {
            "id.missing": "模型ID参数缺失",
            "logo.missing": "请设置模型图标",
            "logo.max_length": "模型图片路径不能超250个字符",
            "name.missing": "请填写模型名称",
            "name.max_length": "模型名称不能超出100个字符",
            "intro.max_length": "模型描述不能超出800个字符",
            "config.missing": "模型配置参数缺失",
            "models.missing": "至少需要1个子模型",
            "is_disable.ge": "模型状态非合法值: [0, 1]",
            "is_disable.le": "模型状态非合法值: [0, 1]"
        }

    class Config:
        json_schema_extra = {
            "example": {
                "id": 1,
                "channel": "openai",
                "logo": "https://www.xx.cn/images/gpt35.png",
                "name": "OpenAI",
                "intro": "OpenAI",
                "is_disable": 0,
                "config": {
                    "context_num": 4,
                    "temperature": 1.0,
                    "presence_penalty": 0.0,
                    "frequency_penalty": 0.0,
                    "check_key": 1,
                    "agency_api": "",
                    "global_directives": ""
                },
                "models": [
                    {
                        "model": "gpt-3.5-turbo",
                        "alias": "gpt35",
                        "price": 0.001,
                        "status": 1
                    },
                    {
                        "model": "gpt-3.5-turbo-0125",
                        "alias": "gpt35-turbo-0125",
                        "price": 0.002,
                        "status": 1
                    }
                ]
            }
        }


class AiModelIdIn(BaseModel):
    """ 模型ID参数 """
    id: int = Field(gt=0, description='模型ID', examples=[1])

    class Config:
        json_schema_extra = {
            'example': {
                'id': 1
            }
        }


"""--------------- Separator ---------------"""


class AiModelsChannelVo(BaseModel):
    """ AI模型渠道Vo """
    chat_models: Dict[str, dict] = Field(description="对话模型通道")
    vector_models: Dict[str, dict] = Field(description="向量模型通道")
    ranking_models: Dict[str, dict] = Field(description="重排模型通道")

    class Config:
        json_schema_extra = {
            "example": {
                "chat_models": [],
                "vector_models": [],
                "ranking_models": []
            }
        }


class AiModelsListVo(BaseModel):
    """ AI模型列表Vo """
    id: int = Field(description="ID")
    logo: str = Field(description="模型图标")
    name: str = Field(description="模型名称")
    sort: int = Field(description="排序编号")
    channel: str = Field(description="模型通道")
    models_num: int = Field(description="子模型数")
    agency_api: int = Field(description="启用代理: [0=否, 1=是]")
    is_builtin: int = Field(description="系统内置: [0=否, 1=是]")
    is_disable: int = Field(description="是否禁用: [0=否, 1=是]")

    class Config:
        json_schema_extra = {
            "example": {
                "id": 1,
                "logo": "https://www.xx.cn/images/gpt35.png",
                "name": "GPT3.5",
                "is_disable": 0
            }
        }


class AiModelsDetailVo(BaseModel):
    """ AI模型详情Vo """
    id: int = Field(description="ID")
    scene: str = Field(description="通道类型")
    mark: str = Field(description="模型标识")
    channel: str = Field(description="模型通道")
    logo: str = Field(description="模型图标")
    name: str = Field(description="模型名称")
    intro: str = Field(description="模型描述")
    is_disable: int = Field(description="是否禁用: [0=否, 1=是]")
    config: list = Field(description="模型配置")
    models: list = Field(description="模型列表")

    class Config:
        json_schema_extra = {
            "example": {
                "id": 1,
                "scene": "chat",
                "mark": "openai",
                "channel": "openai",
                "logo": "https://www.xx.cn/images/gpt35.png",
                "name": "OpenAI",
                "intro": "",
                "is_disable": 0,
                "config": [
                    {
                        "type": "group",
                        "name": "参数配置",
                        "config": [
                            {
                                "key": "context_num",
                                "name": "上下文数",
                                "type": "slider",
                                "default": 4,
                                "range": [
                                    0,
                                    10
                                ],
                                "step": 1,
                                "tips": "根据上下文的信息进行语义理解、识别指代对象并生成连贯的回答"
                            },
                            {
                                "key": "temperature",
                                "name": "温度属性",
                                "type": "slider",
                                "default": 1.0,
                                "range": [
                                    0,
                                    2.0
                                ],
                                "step": 0.1,
                                "tips": "用于控制生成文本的随机性,取值范围为0~2之间的浮点数,建议取值1.0左右"
                            },
                            {
                                "key": "presence_penalty",
                                "name": "存在惩罚",
                                "type": "slider",
                                "default": 0.0,
                                "range": [
                                    -2.0,
                                    2.0
                                ],
                                "step": 0.1,
                                "tips": "用于通过惩罚已经使用的词来增加模型谈论新主题的可能性"
                            },
                            {
                                "key": "frequency_penalty",
                                "name": "频率惩罚",
                                "type": "slider",
                                "default": 0.0,
                                "range": [
                                    -2.0,
                                    2.0
                                ],
                                "step": 0.1,
                                "tips": "用于惩罚已经频繁使用的词来降低模型一行中重复用词的可能性"
                            }
                        ]
                    },
                    {
                        "key": "check_key",
                        "name": "校验密钥",
                        "type": "switch",
                        "default": 1,
                        "tips": "用于应对本地部署模型不需要填密钥的场景"
                    },
                    {
                        "key": "agency_api",
                        "name": "代理域名",
                        "type": "input",
                        "default": "",
                        "tips": "反向代理API域名, 不填写则默认为: https://api.openai.com"
                    },
                    {
                        "key": "global_directives",
                        "name": "对话指令",
                        "type": "input",
                        "default": "",
                        "tips": "设置全局指令, 屏蔽审核人员询问模型类型等相关问题"
                    }
                ],
                "models": [
                    {
                        "model": "gpt-3.5-turbo",
                        "alias": "gpt35",
                        "price": "0.001",
                        "status": 1
                    },
                    {
                        "model": "gpt-3.5-turbo-0125",
                        "alias": "gpt35-turbo-0125",
                        "price": "0.002",
                        "status": 1
                    }
                ]
            }
        }
